﻿using System;
using AreaConverterNamespace;
using System.Collections.Generic;

namespace PresentationNamespace 
{
    public class Presenter
    {
        private static AreaConverter converter = new AreaConverter();
        private ILogger logger;
        private IView view;

        public Presenter(IView view, ILogger logger)
        {
            this.logger = logger;
            logger.ClearLog();
            Setup(view);
            InitializeMeasureTypes();
            view.ErrorMessage = ErrorMessages.NoError;
        }

        public void Setup(IView view)
        {
            this.view = view;
            view.OnConvertClick += ConvertClick;
            view.OnSaveLogAsTxtClick += SaveLogAsTxtClick;
            view.OnShowLogAsTxtClick += ShowLogAsTxtClick;
            view.OnShowLogAsHtmlClick += ShowLogAsHtmlClick;
            view.OnSaveLogAsHtmlClick += SaveLogAsHtmlClick;
            view.LoggerTypeChanged += LoggerTypeChanged;
        }

        private void AddErrorMessages(IEnumerable<string> errorMessages) 
        {
            string allMessages = "";
            foreach (var message in errorMessages)
            {
                allMessages += message + "\n";
                logger.AddMessage("Error: " + message);
            }
            view.ErrorMessage = allMessages;
        }

        private bool ParseInputData(List<string> errorMessages)
        {
            double knownValue;
            bool isCorrect = true;
            
            if (!Double.TryParse(view.KnownValue, out knownValue))
            {
                errorMessages.Add(ErrorMessages.IncorrectValue + view.KnownValue);
                isCorrect = false;
            }
            else if (knownValue < 0.0)
            {
                errorMessages.Add(ErrorMessages.NegativeValue + view.KnownValue);
                isCorrect = false;
            }
            try
            {
                converter.GetMeasureType(view.KnownMeasure);
            }
            catch (UndefinedMeasureTypeException)
            {
                errorMessages.Add(ErrorMessages.IncorrectMeasureType + view.KnownMeasure);
                isCorrect = false;
            }
            try
            {
                converter.GetMeasureType(view.WantedMeasure);
            }
            catch (UndefinedMeasureTypeException)
            {
                errorMessages.Add(ErrorMessages.IncorrectMeasureType + view.WantedMeasure);
                isCorrect = false;
            }

            return isCorrect;
        }

        public void ConvertClick()
        {
            var errorMessages = new List<string>();

            if (!ParseInputData(errorMessages))
            {
                view.WantedValue = "";
                AddErrorMessages(errorMessages);
                return;
            }

            double result = converter.Convert(view.KnownMeasure, view.WantedMeasure, Convert.ToDouble(view.KnownValue));
            view.WantedValue = result.ToString();
            view.ErrorMessage = ErrorMessages.NoError;
            logger.AddMessage("Convert: " + view.KnownValue + " " + view.KnownMeasure + " = " + 
                result.ToString() + " " + view.WantedMeasure);          
        }

        private void InitializeMeasureTypes()
        {
            var array = new string[converter.GetAvailableMeasuresCount()];
            array = converter.GetAvailableMeasureNames().ToArray();
            view.MeasureTypes = array;
        }

        private bool CheckLogFileName()
        {
            if (view.LogFileName == "")
            {
                view.ErrorMessage = ErrorMessages.FileDontExist;
                logger.AddMessage("Error: " + ErrorMessages.FileDontExist);
                return false;
            }
            return true;
        }

        public void SaveLogAsTxtClick()
        {
            if (!CheckLogFileName())
                return;
            logger.AddMessage("Save log to text file " + view.LogFileName);
            
            if (view.IsTxtLoggerSelected)
            {
                logger.WriteMessages(view.LogFileName);
            }
            else 
            {
                var txtLogger = view.CreateTxtLogger();
                CopyLogHistory(logger, txtLogger);
                txtLogger.WriteMessages(view.LogFileName);
            }
        }

        public void ShowLogAsTxtClick()
        {
            view.LogText = logger.GetLoggerHistory().ToArray();
        }

        public void ShowLogAsHtmlClick()
        {
            if (!view.IsHtmlLoggerSelected)
            {
                var htmlLogger = view.CreateHtmlLogger();
                CopyLogHistory(logger, htmlLogger);
                view.LogText = htmlLogger.GetLogMessages().ToArray();
            }
            else
            {
                view.LogText = logger.GetLogMessages().ToArray();
            }
        }

        private void CopyLogHistory(ILogger oldLogger, ILogger newLogger)
        {
            var oldHistory = oldLogger.GetLoggerHistory();
            foreach (var message in oldHistory)
            {
                newLogger.AddMessage(message);
            }
        }

        public void ChangeLogger(ILogger newLogger)
        {
            CopyLogHistory(logger, newLogger);
            logger = newLogger;
        }

        public void SaveLogAsHtmlClick()
        {
            if (!CheckLogFileName())
                return;

            logger.AddMessage("Save log to html file " + view.LogFileName);
            if (!view.IsHtmlLoggerSelected)
            {
                var htmlLogger = view.CreateHtmlLogger();
                CopyLogHistory(logger, htmlLogger);
                htmlLogger.WriteMessages(view.LogFileName);
            }
            else
            {
                logger.WriteMessages(view.LogFileName);
            }
        }

        public void LoggerTypeChanged()
        {
            if (view.IsHtmlLoggerSelected)
            {
                ChangeLogger(view.CreateHtmlLogger());
                logger.AddMessage("Logger type changed to html");
            }
            else
            {
                ChangeLogger(view.CreateTxtLogger());
                logger.AddMessage("Logger type changed to txt");
            }
        }
    
    }
}
